package sample.stock;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.AndroidHttpTransport;

import sample.stock.model.Stock;
import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.database.Cursor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemSelectedListener;

import com.csvreader.CsvReader;

public class StockVN extends Activity {
	private Button next = null;
	private Button update = null;
	private Spinner sp = null;
	private Spinner chart = null;
	private TextView ticker = null;
	private TextView open = null;
	private TextView high = null;
	private TextView low = null;
	private TextView close = null;
	private TextView volume = null;

	private static String SOAP_ACTION = "http://tempuri.org/GetAllTickers";
	private static String NAMESPACE = "http://tempuri.org/";
	private static String METHOD_NAME = "GetAllTickers";
	/*
	 * Vu's computer:
	 */
	private static String URL = "http://localhost:2489/Service1.asmx";

	private ProgressDialog progressDialog;

	private EditText mDate;
	private int mYear;
	private int mMonth;
	private int mDay;

	static final int DATE_DIALOG_ID = 0;

	private String open_price = "";
	private String high_price = "";
	private String low_price = "";
	private String close_price = "";
	private String volumes = "";

	private EditText startDate;
	private EditText endDate;

	// the callback received when the user "sets" the date in the dialog
	private DatePickerDialog.OnDateSetListener mDateSetListener = new DatePickerDialog.OnDateSetListener() {
		@Override
		public void onDateSet(DatePicker view, int year, int monthOfYear,
				int dayOfMonth) {
			mYear = year;
			mMonth = monthOfYear;
			mDay = dayOfMonth;
			updateDisplay();
			getDates();
			// after change date, auto update ticker
			progressDialog = new ProgressDialog(StockVN.this);
			progressDialog.setMessage("Loading...");
			new LoadStockTask(progressDialog).execute();
		}
	};

	@Override
	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case DATE_DIALOG_ID:
			return new DatePickerDialog(this, mDateSetListener, mYear, mMonth,
					mDay);
		}
		return null;
	}

	@SuppressWarnings("unchecked")
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.stockvn);
		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

		ticker = (TextView) findViewById(R.id.ticker);
		open = (TextView) findViewById(R.id.open);
		high = (TextView) findViewById(R.id.high);
		low = (TextView) findViewById(R.id.low);
		close = (TextView) findViewById(R.id.close);
		volume = (TextView) findViewById(R.id.volume);
		sp = (Spinner) findViewById(R.id.spinner1);
		chart = (Spinner) findViewById(R.id.spinner2);
		startDate = (EditText) findViewById(R.id.startDate);
		endDate = (EditText) findViewById(R.id.endDate);

		ArrayAdapter adapter = ArrayAdapter.createFromResource(this,
				R.array.vnchartoptions, android.R.layout.simple_spinner_item);
		chart.setAdapter(adapter);
		chart.setOnItemSelectedListener(new OnItemSelectedListener() {
			@Override
			public void onItemSelected(AdapterView<?> arg0, View arg1,
					int arg2, long arg3) {
			}

			@Override
			public void onNothingSelected(AdapterView<?> arg0) {
				Toast.makeText(getApplicationContext(), "Nothing selected",
						Toast.LENGTH_SHORT).show();
			}
		});

		// capture our View elements
		mDate = (EditText) findViewById(R.id.editText1);

		// get the current date
		final Calendar c = Calendar.getInstance();
		mYear = c.get(Calendar.YEAR);
		mMonth = c.get(Calendar.MONTH);
		mDay = c.get(Calendar.DAY_OF_MONTH);

		// display the current date (this method is below)
		updateDisplay();
		getDates();

		progressDialog = new ProgressDialog(StockVN.this);
		progressDialog.setMessage("Loading...");
		new LoadSpinnerTask(progressDialog).execute();
		sp.setOnItemSelectedListener(new OnItemSelectedListener() {
			@Override
			public void onItemSelected(AdapterView<?> arg0, View arg1,
					int arg2, long arg3) {
				progressDialog = new ProgressDialog(StockVN.this);
				progressDialog.setMessage("Loading...");
				new LoadStockTask(progressDialog).execute();
			}

			@Override
			public void onNothingSelected(AdapterView<?> arg0) {
				Toast.makeText(getApplicationContext(), "Nothing selected",
						Toast.LENGTH_SHORT).show();
			}
		});

		next = (Button) findViewById(R.id.button1);
		next.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				String sDate = startDate.getText().toString();
				String eDate = endDate.getText().toString();
				if (!sDate.isEmpty() && !eDate.isEmpty()) {
					String symbol = ticker.getText().toString();
					String urlChart = "";
					switch (chart.getSelectedItemPosition()) {
					case 0:
					default:
						urlChart = "http://www.cophieu68.com/chartsymbol_chart.php?s="
								+ sDate
								+ "&e="
								+ eDate
								+ "&m=line&dateby=1&chartsize=1&id=" + symbol;
						break;
					case 1:
						urlChart = "http://www.cophieu68.com/chartsymbol_chart.php?s="
								+ sDate
								+ "&e="
								+ eDate
								+ "&m=candle&dateby=1&chartsize=1&id=" + symbol;
						break;
					}
					Intent chartView = new Intent(StockVN.this, GChart.class);
					chartView.putExtra("url", urlChart);
					startActivity(chartView);
				} else {
					Toast.makeText(StockVN.this, "Input start & end date.",
							Toast.LENGTH_LONG);
				}
			}
		});

		update = (Button) findViewById(R.id.button3);
		update.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				showDialog(DATE_DIALOG_ID);
			}
		});
	}

	private void updateDisplay() {
		String date = Integer.toString(mMonth + 1) + "/"
				+ Integer.toString(mDay) + "/" + Integer.toString(mYear);
		mDate.setText(date);
	}

	private void getDates() {
		String date = Integer.toString(mYear) + "-"
				+ Integer.toString(mMonth + 1) + "-" + Integer.toString(mDay);
		endDate.setText(date);
		date = Integer.toString(mYear) + "-" + Integer.toString(mMonth) + "-"
				+ Integer.toString(mDay);
		startDate.setText(date);
	}

	private class LoadStockTask extends AsyncTask<Void, Void, Void> {
		private ProgressDialog progress;
		private Stock stock = null;

		public LoadStockTask(ProgressDialog progress) {
			this.progress = progress;
		}

		public void onPreExecute() {
			progress.show();
		}

		public void onPostExecute(Void unused) {
			if (stock != null)
				DisplayStock(stock);
			else
				Toast.makeText(StockVN.this, "Data not found.",
						Toast.LENGTH_SHORT);
			progress.dismiss();
		}

		@SuppressWarnings("deprecation")
		@Override
		protected Void doInBackground(Void... arg0) {
			String ticker = sp.getSelectedItem().toString();
			String date = mDate.getText().toString();
			SOAP_ACTION = "http://tempuri.org/GetTickerByDate";
			METHOD_NAME = "GetTickerByDate";

			SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME);
			Request.addProperty("ticker", ticker); // replace by selected ticker
													// in spinner
			Request.addProperty("date", date); // current date

			SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(
					SoapEnvelope.VER11);
			soapEnvelope.dotNet = true;
			soapEnvelope.setOutputSoapObject(Request);

			AndroidHttpTransport aht = new AndroidHttpTransport(URL);
			try {
				aht.call(SOAP_ACTION, soapEnvelope);
				SoapObject responseResult = (SoapObject) soapEnvelope
						.getResponse();
				SoapObject resultDataSet = (SoapObject) responseResult
						.getProperty(1);
				stock = ParseSoapResponse_Stock(resultDataSet);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return null;
		}
	}

	private class LoadSpinnerTask extends AsyncTask<Void, Void, Void> {
		private ProgressDialog progress;
		private String[] spinner = null;

		public LoadSpinnerTask(ProgressDialog progress) {
			this.progress = progress;
		}

		public void onPreExecute() {
			progress.show();
		}

		@SuppressWarnings("unchecked")
		public void onPostExecute(Void unused) {
			if (spinner != null) {
				ArrayAdapter spinnerArrayAdapter = new ArrayAdapter(
						StockVN.this, android.R.layout.simple_spinner_item,
						spinner);
				sp.setAdapter(spinnerArrayAdapter);
			}
			progress.dismiss();
		}

		@SuppressWarnings("deprecation")
		@Override
		protected Void doInBackground(Void... arg0) {
			SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME);

			SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(
					SoapEnvelope.VER11);
			soapEnvelope.dotNet = true;
			soapEnvelope.setOutputSoapObject(Request);

			AndroidHttpTransport aht = new AndroidHttpTransport(URL);

			try {
				aht.call(SOAP_ACTION, soapEnvelope);
				SoapObject responseResult = (SoapObject) soapEnvelope
						.getResponse();
				spinner = ParseSoapResponse_Tickers(responseResult);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return null;
		}
	}

	private class LoadDataTask extends AsyncTask<Void, Void, Void> {
		private ProgressDialog progress;
		private List<Stock> stockPrices = new ArrayList<Stock>();

		public LoadDataTask(ProgressDialog progress) {
			this.progress = progress;
		}

		public void onPreExecute() {
			progress.show();
		}

		public void onPostExecute(Void unused) {
			if (open_price != "") {
				Intent chartView = new Intent(StockVN.this, GChart.class);
				chartView.putExtra("open_price", open_price);
				chartView.putExtra("high_price", high_price);
				chartView.putExtra("low_price", low_price);
				chartView.putExtra("close_price", close_price);
				chartView.putExtra("volumes", volumes);
				startActivity(chartView);
			}
			progress.dismiss();
		}

		@SuppressWarnings("deprecation")
		@Override
		protected Void doInBackground(Void... arg0) {
			String ticker = sp.getSelectedItem().toString();
			// get the current date
			final Calendar c = Calendar.getInstance();
			int eYear = c.get(Calendar.YEAR);
			int eMonth = c.get(Calendar.MONTH) + 1;
			int eDay = c.get(Calendar.DAY_OF_MONTH);

			String endDate = eMonth + "/" + eDay + "/" + eYear; // current date
			String startDate = mDate.getText().toString();

			SOAP_ACTION = "http://tempuri.org/GetTickerPrices";
			METHOD_NAME = "GetTickerPrices";

			SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME);
			Request.addProperty("ticker", ticker);
			Request.addProperty("startDate", startDate);
			Request.addProperty("endDate", endDate);

			SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(
					SoapEnvelope.VER11);
			soapEnvelope.dotNet = true;
			soapEnvelope.setOutputSoapObject(Request);

			AndroidHttpTransport aht = new AndroidHttpTransport(URL);
			try {
				aht.call(SOAP_ACTION, soapEnvelope);
				SoapObject responseResult = (SoapObject) soapEnvelope
						.getResponse();
				SoapObject resultDataSet = (SoapObject) responseResult
						.getProperty(1);
				stockPrices = ParseSoapResponse_Stocks(resultDataSet);
				for (int i = 0; i < stockPrices.size(); i++) {
					open_price += stockPrices.get(i).open + ",";
					high_price += stockPrices.get(i).high + ",";
					low_price += stockPrices.get(i).low + ",";
					close_price += stockPrices.get(i).close + ",";
					volumes += stockPrices.get(i).volume + ",";
				}
				open_price = open_price.substring(0, open_price.length() - 1);
				high_price = open_price.substring(0, high_price.length() - 1);
				low_price = open_price.substring(0, low_price.length() - 1);
				close_price = open_price.substring(0, close_price.length() - 1);
				volumes = open_price.substring(0, volumes.length() - 1);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return null;
		}
	}

	public List<Stock> ParseSoapResponse_Stocks(SoapObject result) {
		String temp = result.toString();
		temp = temp.replace("anyType", "");
		temp = temp.replace("Table=", "");
		temp = temp.replace("NewDataSet=", "");
		temp = temp.replace("{", "");
		String[] elements = temp.split("\\}");
		List<Stock> stockPrices = new ArrayList<Stock>();
		for (int i = 0; i < elements.length; i++) {
			if (elements[i].length() > 2) {
				Stock stock = new Stock();
				stock.ticker = elements[i].substring(elements[i]
						.indexOf("ticker=") + 7, elements[i].indexOf(";",
						elements[i].indexOf("ticker=")));
				stock.date = elements[i].substring(
						elements[i].indexOf("date=") + 5,
						elements[i].indexOf(";", elements[i].indexOf("date=")));
				stock.open = elements[i].substring(
						elements[i].indexOf("open_price=") + 11,
						elements[i].indexOf(";",
								elements[i].indexOf("open_price=")));
				stock.high = elements[i].substring(
						elements[i].indexOf("high_price=") + 11,
						elements[i].indexOf(";",
								elements[i].indexOf("high_price=")));
				stock.low = elements[i].substring(
						elements[i].indexOf("low_price=") + 10,
						elements[i].indexOf(";",
								elements[i].indexOf("low_price=")));
				stock.close = elements[i].substring(
						elements[i].indexOf("close_price=") + 11,
						elements[i].indexOf(";",
								elements[i].indexOf("close_price=")));
				stock.volume = elements[i].substring(elements[i]
						.indexOf("volume=") + 6, elements[i].indexOf(";",
						elements[i].indexOf("volume=")));
				stockPrices.add(stock);
			}
		}

		return stockPrices;
	}

	public String[] ParseSoapResponse_Tickers(SoapObject result) {
		String temp = result.toString();
		temp = temp.substring(8);
		temp = temp.replaceAll(" ", "");
		temp = temp.replace("}", "");
		String[] tickers = temp.split(";");
		String[] spTickers = new String[tickers.length];
		for (int i = 0; i < tickers.length; i++) {
			spTickers[i] = tickers[i].substring(7);
		}
		return spTickers;
	}

	public Stock ParseSoapResponse_Stock(SoapObject result) {
		String temp = result.toString();
		temp = temp.replace("anyType", "");
		temp = temp.replace("Table=", "");
		temp = temp.replace("NewDataSet=", "");
		temp = temp.replace("{", "");

		Stock stock = new Stock();
		stock.ticker = temp.substring(temp.indexOf("ticker=") + 7,
				temp.indexOf(";", temp.indexOf("ticker=")));
		stock.date = temp.substring(temp.indexOf("date=") + 5,
				temp.indexOf(";", temp.indexOf("date=")));
		stock.open = temp.substring(temp.indexOf("open_price=") + 11,
				temp.indexOf(";", temp.indexOf("open_price=")));
		stock.high = temp.substring(temp.indexOf("high_price=") + 11,
				temp.indexOf(";", temp.indexOf("high_price=")));
		stock.low = temp.substring(temp.indexOf("low_price=") + 10,
				temp.indexOf(";", temp.indexOf("low_price=")));
		stock.close = temp.substring(temp.indexOf("close_price=") + 12,
				temp.indexOf(";", temp.indexOf("close_price=")));
		stock.volume = temp.substring(temp.indexOf("volume=") + 7,
				temp.indexOf(";", temp.indexOf("volume=")));

		return stock;
	}

	public void DisplayStock(Stock s) {
		ticker.setText(s.ticker);
		open.setText(s.open);
		high.setText(s.high);
		low.setText(s.low);
		close.setText(s.close);
		volume.setText(s.volume);
	}

	public void DisplayStock(Cursor c) {
		Toast.makeText(
				this,
				"id: " + c.getString(0) + "\n" + "Ticker: " + c.getString(1)
						+ "\n" + "Date: " + c.getString(2) + "\n" + "Open:  "
						+ c.getString(3) + "\n" + "High:  " + c.getString(4)
						+ "\n" + "Low:  " + c.getString(5) + "\n" + "Close:  "
						+ c.getString(6) + "\n" + "Volume:  " + c.getString(7),
				Toast.LENGTH_LONG).show();
	}

	public void DownloadFromUrl(String DownloadUrl, String fileName) {
		try {
			File root = android.os.Environment.getExternalStorageDirectory();
			File dir = new File(root.getAbsolutePath() + "/stocks");
			if (dir.exists() == false) {
				dir.mkdirs();
			}

			File file = new File(dir, fileName);

			long startTime = System.currentTimeMillis();
			Log.d("DownloadManager", "download begining");
			Log.d("DownloadManager", "download url:" + DownloadUrl);
			Log.d("DownloadManager", "downloaded file name:" + fileName);

			// create the new connection
			HttpClient client = new DefaultHttpClient();
			HttpGet request = new HttpGet();
			request.setURI(new URI(DownloadUrl));
			HttpResponse response = client.execute(request);

			// this will be used in reading the data from the internet
			InputStream inputStream = response.getEntity().getContent();

			// variable to store total downloaded bytes
			int downloadedSize = 0;

			// this will be used to write the downloaded data into the file we
			// created
			FileOutputStream fileOutput = new FileOutputStream(file);

			// create a buffer...
			byte[] buffer = new byte[1024];
			int bufferLength = 0; // used to store a temporary size of the
									// buffer

			// now, read through the input buffer and write the contents to the
			// file
			while ((bufferLength = inputStream.read(buffer)) > 0) {
				// add the data in the buffer to the file in the file output
				// stream (the file on the sd card
				fileOutput.write(buffer, 0, bufferLength);
				// add up the size so we know how much is downloaded
				downloadedSize += bufferLength;
			}
			// close the output stream when done
			fileOutput.close();

			Log.d("DownloadManager",
					"download ready in"
							+ ((System.currentTimeMillis() - startTime) / 1000)
							+ " sec");
			Log.d("DOwnloadManager", "download size" + downloadedSize);
			Context ctx = getApplicationContext();
			Toast.makeText(ctx, "DONE", Toast.LENGTH_SHORT).show();

		} catch (IOException e) {
			Log.d("DownloadManager", "Error: " + e);
		} catch (URISyntaxException e) {
			Log.d("DownloadManager", "Error: " + e);
			e.printStackTrace();
		}

	}

	public void ReadCSV(String fileName) {
		try {
			File root = android.os.Environment.getExternalStorageDirectory();
			// File dir = new File (root.getAbsolutePath() + "/stocks");
			CsvReader products = new CsvReader(new FileReader(
					root.getAbsolutePath() + "/stocks/" + fileName));
			List<Stock> stockList = new ArrayList<Stock>();

			products.readHeaders();
			while (products.readRecord()) {
				Stock newStock = new Stock();
				newStock.ticker = products.get("<Ticker>");
				newStock.date = products.get("<DTYYYYMMDD>");
				newStock.open = products.get("<Open>");
				newStock.high = products.get("<High>");
				newStock.low = products.get("<Low>");
				newStock.close = products.get("<Close>");
				newStock.volume = products.get("<Volume>");

				stockList.add(newStock);
			}

			products.close();

		} catch (FileNotFoundException e) {
			Context context = getApplicationContext();
			CharSequence text = "File Not Found";
			int duration = Toast.LENGTH_SHORT;
			Toast toast = Toast.makeText(context, text, duration);
			toast.show();
			e.printStackTrace();
		} catch (IOException e) {
			Context context = getApplicationContext();
			CharSequence text = "IOException";
			int duration = Toast.LENGTH_SHORT;
			Toast toast = Toast.makeText(context, text, duration);
			toast.show();
			e.printStackTrace();
		}
	}
}